package com.rtx.wms.std.handler.asn.dowm;

import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSON;
import com.rtx.common.HttpServletRequestUtil;
import com.rtx.model.dto.edi.EdiInnerRequestDTO;
import com.rtx.wms.std.asn.bean.ApiReceipt;
import com.rtx.wms.std.asn.bean.ApiReceiptdetail;
import com.rtx.wms.std.asn.mapper.dymapper.DyApiReceiptMapper;
import com.rtx.wms.std.asn.mapper.dymapper.DyApiReceiptdetailMapper;
import com.rtx.wms.std.asn.service.ApiReceiptService;
import com.rtx.wms.std.asn.service.ReceiptService;
import com.rtx.wms.std.common.bean.WmsConstant;
import com.rtx.wms.std.ctclass.ClassHolder;
import com.rtx.wms.std.qm.service.ReceiverinfoQueryService;
import com.rtx.wms.std.sku.bean.po.Sku;
import com.rtx.wms.std.validation.asn.ReceiptValidation;


/**
 * 入库单下发
 */
@SuppressWarnings("all")
public abstract class AbstractReceiptDownHandler {
	
	
    @Autowired
    protected ApiReceiptService apiReceiptService;

    @Autowired
    protected ReceiptValidation receiptValidation;

    @Autowired
    protected ReceiptService receiptService;

    @Autowired
    protected ReceiverinfoQueryService receiverinfoQueryService;
    
    /**
     * 创建出库单
     * @param apiReceipt
     */
    public void createReceipt(HttpServletRequest request){
    	
    	ApiReceipt apiReceipt = null;
    	
      	String requestStr = HttpServletRequestUtil.getHttpBody(request);
		EdiInnerRequestDTO dto = JSON.parseObject(requestStr, EdiInnerRequestDTO.class);
		request.setAttribute("config", dto.getConfig());
    	
    	if(StringUtils.hasLength(dto.getConfig().getPreconfig())) {
    		//预处理
    		apiReceipt = preHandle(request);
    	}
    	
    	if(null == apiReceipt) {
    		apiReceipt = addExternalColumns(dto.getTagetjson(),dto);
    	}
    	
        //验证出库单
        validationApiReceipt(apiReceipt);
        
        //插入之前
        preinsert(apiReceipt,request);
        
        //根据“外部单号”查询RECEIPT表中是否存在，如果没有就新建一个WMS入库单。
        receiptService.handlerExistsReceipt(apiReceipt.getWhseid(),apiReceipt.getExternreceiptkey());
        
        //写入中间表
        insertApiReceipt(apiReceipt,dto);
    }
    
    
    /**
     * 插入表之前处理客制化新增字段
     * @throws InvocationTargetException 
     * @throws Exception 
     * 
     */
    public ApiReceipt addExternalColumns(String targetJson,EdiInnerRequestDTO dto){
    	ApiReceipt head = null;
    	try {
        	String apiid =  dto.getConfig().getTargetapiid();
        	Map<String,Class> map = ClassHolder.apiconfigClassMap.get(apiid);
        	Class headclass =map.get("main");
        	Class subclass =map.get("sub");
            if(headclass != null){
                head = (ApiReceipt) JSON.parseObject(targetJson,headclass);
            }else{
                head = JSON.parseObject(targetJson,ApiReceipt.class);
            }
        	if(subclass != null){
                List<ApiReceiptdetail> sub = JSON.parseArray(JSON.parseObject(targetJson).getString("details") ,subclass);
                head.setDetails(sub);
            }else{
                List<ApiReceiptdetail> sub = JSON.parseArray(JSON.parseObject(targetJson).getString("details") ,ApiReceiptdetail.class);
                head.setDetails(sub);
            }
		} catch (Exception e) {
			e.printStackTrace();
		}

    	return head;
    }
    
    /**
     * 进入处理方法之前
     */
    protected abstract ApiReceipt preHandle(HttpServletRequest request);
    
    /**
     * 在insert 之后
     * @param request
     * @return
     */
    protected abstract void preinsert(ApiReceipt r,HttpServletRequest request);
    

    /**
     * 写入出库单
     * @param apiReceipt
     */
    protected void insertApiReceipt(ApiReceipt apiReceipt,EdiInnerRequestDTO dto) {
        //新增出库单
        apiReceiptService.addApiReceipt("ris_edi",apiReceipt,dto);
    }

    /**
     * 验证出库订单
     * @param apiReceipt
     */
    protected void validationApiReceipt(ApiReceipt apiReceipt) {
        for(ApiReceiptdetail detail : apiReceipt.getDetails()){
            //仓库
            detail.setWhseid(apiReceipt.getWhseid());
            //货主
            detail.setStorerkey(apiReceipt.getStorerkey());
            //校验接口表中的SKU是否在该仓库下存在，不存在终止程序，写入“SKU不存在”报错数据到ERRMS
            Sku sku = receiptValidation.validationSku(WmsConstant.ENTERPRISE, detail.getStorerkey(), detail.getSku(), true);
            //单位
            detail.setUom("EA");
            //包装
            detail.setPackkey(sku.getPackkey());
        }
        //特定验证
        validationSpecific(apiReceipt);
    }

    /**
     * 特定验证
     * @param apiReceipt
     */
    protected abstract void validationSpecific(ApiReceipt apiReceipt);
}
